home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 June / EnigmA AMIGA RUN 19 (1997)(G.R. Edizioni)(IT)[!][issue 1997-06][EAR-CD III].iso / softwareupdate / cybergraphix update / cgxdpms.lha / CGXDPMS.c < prev    next >
C/C++ Source or Header  |  1997-05-09  |  12KB  |  651 lines

  1. #define __USE_SYSBASE    1
  2. #include <clib/alib_protos.h>
  3. #include <exec/alerts.h>
  4. #include <exec/execbase.h>
  5. #include <exec/memory.h>
  6. #include <intuition/intuitionbase.h>
  7. #include <libraries/cybergraphics.h>
  8. #include <proto/commodities.h>
  9. #include <proto/cybergraphics.h>
  10. #include <proto/dos.h>
  11. #include <proto/exec.h>
  12. #include <proto/intuition.h>
  13. #include <proto/icon.h>
  14. #include <proto/utility.h>
  15. #include <workbench/startup.h>
  16. #include <string.h>
  17.  
  18.  
  19. /* Compiler specific stuff. */
  20. #define SAVEDS    __saveds
  21. #define ASM    __asm
  22. #define REG(x)    register __ ## x
  23. #define STKARGS    __stdargs
  24.  
  25. #define VERSION    "1.0"
  26. #define DATE    "9.5.97"
  27.  
  28.  
  29. /******************** Global variables ********************/
  30.  
  31.  
  32. struct NewBroker    NewBroker =
  33. {
  34.     NB_VERSION,
  35.     "CGXDPMS",
  36.     "CGXDPMS " VERSION "by Magnus Holmgren",
  37.     "DPMS manager for CyberGraphX",
  38.     NBU_UNIQUE, 0, 0,
  39.     NULL, 0
  40. };
  41.  
  42. struct Library        *CxBase;
  43. struct Library        *CyberGfxBase;
  44. struct DosLibrary    *DOSBase;
  45. struct Library        *IconBase;
  46. struct IntuitionBase    *IntuitionBase;
  47. struct ExecBase        *SysBase;
  48. struct Library        *UtilityBase;
  49.  
  50. struct MsgPort        *CxPort;
  51. struct WBStartup    *WBMsg;
  52. CxObj            *Broker, *Sender, *Custom;
  53.  
  54. LONG    StandbyTime,    SuspendTime,    OffTime, IETime;
  55. LONG    StandbyCounter, SuspendCounter, OffCounter;
  56. LONG    SendShift, NoMouse, State, FinalState;
  57.  
  58. struct InputEvent    ShiftDown, ShiftUp;
  59.  
  60.  
  61. #define DEF_CXPRI    1
  62. #define DEF_STANDBY    20
  63. #define DEF_SUSPEND    20
  64. #define DEF_OFF        20
  65. #define DEF_SENDSHIFT    1
  66.  
  67. #define ID_SENDER    49
  68. #define ID_CUSTOM    17
  69. #define MAGIC    ( APTR ) 87654321L
  70.  
  71. struct Args
  72. {
  73.     LONG    *CxPriority;
  74.     LONG    *StandbyTime;
  75.     LONG    *SuspendTime;
  76.     LONG    *OffTime;
  77.     LONG    *ShiftTime;
  78.     LONG    SendShift;
  79.     LONG    NoMouse;
  80. };
  81.  
  82. #define TEMPLATE "CX_PRIORITY/K/N,STANDBYTIME/K/N,SUSPENDTIME/K/N,OFFTIME/K/N,SHIFTTIME/K/N,SENDSHIFT/S,NOMOUSE/S"
  83.  
  84.  
  85. /******************** Startup code ********************/
  86.  
  87.  
  88. static LONG    Main( VOID );
  89.  
  90.  
  91. SAVEDS LONG
  92. Startup( VOID )
  93. {
  94.     LONG    r;
  95.  
  96.     SysBase = *( ( struct ExecBase ** ) 4 );
  97.  
  98.     {
  99.         struct Process    *thisTask = ( struct Process * ) FindTask( NULL );
  100.  
  101.         if( !thisTask->pr_CLI )
  102.         {
  103.             /* Handle Workbench startup message */
  104.             struct MsgPort    *port = &thisTask->pr_MsgPort;
  105.  
  106.             WaitPort( port );
  107.             WBMsg = ( struct WBStartup * ) GetMsg( port );
  108.         }
  109.     }
  110.  
  111.     SetSignal( 0, SIGBREAKF_CTRL_C );
  112.  
  113.     if( SysBase->LibNode.lib_Version >= 37 )
  114.     {
  115.         r = Main();
  116.     }
  117.     else
  118.     {
  119.         r = 100;
  120.     }
  121.  
  122.     if( WBMsg )
  123.     {
  124.         Forbid();
  125.         ReplyMsg( ( struct Message * ) WBMsg );
  126.     }
  127.  
  128.     return( r );
  129. }
  130.  
  131.  
  132. /******************** String constants ********************/
  133.  
  134.  
  135. static const TEXT Ver[]    = "$VER: CGXDPMS " VERSION " (" DATE ")";
  136.  
  137.  
  138. /******************** Misc ********************/
  139.  
  140.  
  141. static LONG
  142. MyRequest( STRPTR title, STRPTR body, STRPTR gads, ... )
  143. {
  144.     struct EasyStruct    es;
  145.  
  146.     es.es_StructSize = sizeof( es );
  147.     es.es_Flags = 0;
  148.     es.es_Title = title;
  149.     es.es_TextFormat = body;
  150.     es.es_GadgetFormat = gads;
  151.     return( EasyRequestArgs( NULL, &es, NULL, &gads + 1 ) );
  152. }
  153.  
  154.  
  155. static VOID
  156. ErrRequest( STRPTR body, ... )
  157. {
  158.     if( WBMsg )
  159.     {
  160.         MyRequest( "CGXDPMS error message", body, "Quit", &body + 1 );
  161.     }
  162.     else
  163.     {
  164.         VPrintf( body, &body + 1 );
  165.     }
  166. }
  167.  
  168.  
  169. /******************** Libs ********************/
  170.  
  171.  
  172. static struct Library *
  173. OpenLib( STRPTR name, LONG ver )
  174. {
  175.     struct Library    *lib;
  176.  
  177.     if( !( lib = OpenLibrary( name, ver ) ) )
  178.     {
  179.         ErrRequest( "Couldn't open %s\nversion %ld or higher!", name, ver );
  180.     }
  181.  
  182.     return( lib );
  183. }
  184.  
  185.  
  186. #define CloseLib(lib)    CloseLibrary( ( struct Library * ) lib )
  187.  
  188.  
  189. static VOID
  190. CloseLibs( VOID )
  191. {
  192.     if( DOSBase )
  193.     {
  194.         CloseLib( DOSBase );
  195.         CloseLib( IntuitionBase );
  196.         CloseLib( UtilityBase );
  197.         CloseLib( CyberGfxBase );
  198.         CloseLib( CxBase );
  199.     }
  200. }
  201.  
  202.  
  203. static BOOL
  204. OpenLibs( VOID )
  205. {
  206.     BOOL    rc = FALSE;
  207.  
  208.     if( DOSBase = ( struct DosLibrary * ) OpenLibrary( "dos.library", 37 ) )
  209.     {
  210.         if( IntuitionBase = ( struct IntuitionBase * ) OpenLibrary( "intuition.library", 37 ) )
  211.         {
  212.             if( ( UtilityBase = OpenLib( "utility.library", 37 ) )
  213.                 && ( CyberGfxBase = OpenLib( "cybergraphics.library", 40 ) )
  214.                 && ( CxBase = OpenLib( "commodities.library", 37 ) ) )
  215.             {
  216.                 rc = TRUE;
  217.             }
  218.         }
  219.         else
  220.         {
  221.             Alert( AT_Recovery | AN_Unknown | AG_OpenLib | AO_Intuition );
  222.         }
  223.     }
  224.     else
  225.     {
  226.         Alert( AT_Recovery | AN_Unknown | AG_OpenLib | AO_DOSLib );
  227.     }
  228.  
  229.     return( rc );
  230. }
  231.  
  232.  
  233. /******************** Argument parsing ********************/
  234.  
  235.  
  236. static LONG
  237. GetTimeTT( const struct DiskObject *icon, STRPTR name, LONG def )
  238. {
  239.     STRPTR    str;
  240.     LONG    val;
  241.  
  242.     val = def;
  243.  
  244.     if( str = FindToolType( icon->do_ToolTypes, name ) )
  245.     {
  246.         if( StrToLong( str, &val ) == -1 )
  247.         {
  248.             MyRequest( "CGXDMPS Warning", "Argument for %s should be numeric.\nUsing default (%ld).", name, def );
  249.             val = def;
  250.         }
  251.     }
  252.  
  253.     return( SMult32( val, 60 ) );
  254. }
  255.  
  256.  
  257. static BOOL
  258. ParseWBArgs( VOID )
  259. {
  260.     BOOL    rc = FALSE;
  261.  
  262.     if( IconBase = OpenLib( "icon.library", 37 ) )
  263.     {
  264.         struct DiskObject    *icon;
  265.         BPTR    oldDir;
  266.  
  267.         oldDir = CurrentDir( WBMsg->sm_ArgList[ 0 ].wa_Lock );
  268.  
  269.         /* Lazy parsing: Ignore any multiselected icons... */
  270.         if( icon = GetDiskObject( WBMsg->sm_ArgList[ 0 ].wa_Name ) )
  271.         {
  272.             NewBroker.nb_Pri = GetTimeTT( icon, "CX_PRIORITY", DEF_CXPRI );
  273.             StandbyTime      = GetTimeTT( icon, "STANDBYTIME", DEF_STANDBY );
  274.             SuspendTime      = GetTimeTT( icon, "SUSPENDTIME", DEF_SUSPEND );
  275.             OffTime          = GetTimeTT( icon, "OFFTIME",     DEF_OFF );
  276.             IETime           = GetTimeTT( icon, "SHIFTTIME",   DEF_SENDSHIFT );
  277.             SendShift        = ( LONG ) FindToolType( icon->do_ToolTypes, "SENDSHIFT" );
  278.             NoMouse          = ( LONG ) FindToolType( icon->do_ToolTypes, "NOMOUSE" );
  279.             rc = TRUE;
  280.  
  281.             FreeDiskObject( icon );
  282.         }
  283.         else
  284.         {
  285.             ErrRequest( "Couldn't get program icon!" );
  286.         }
  287.  
  288.         CurrentDir( oldDir );
  289.         CloseLibrary( IconBase );
  290.     }
  291.     else
  292.     {
  293.         ErrRequest( "Couldn't open icon.library\nversion 37 or higher!" );
  294.     }
  295.  
  296.     return( rc );
  297. }
  298.  
  299.  
  300. static LONG
  301. GetTime( LONG *val, LONG def )
  302. {
  303.     LONG    rc;
  304.  
  305.     rc = def;
  306.  
  307.     if( val )
  308.     {
  309.         rc = *val;
  310.     }
  311.  
  312.     return( SMult32( rc, 60 ) );
  313. }
  314.  
  315.  
  316. static BOOL
  317. ParseCLIArgs( VOID )
  318. {
  319.     struct Args    args;
  320.     struct RDArgs    *rdarg;
  321.     BOOL    rc = FALSE;
  322.  
  323.     memset( &args, 0, sizeof( args ) );
  324.  
  325.     if( rdarg = ReadArgs( TEMPLATE, ( LONG * ) &args, NULL ) )
  326.     {
  327.         NewBroker.nb_Pri = GetTime( args.CxPriority,  DEF_CXPRI );
  328.         StandbyTime      = GetTime( args.StandbyTime, DEF_STANDBY );
  329.         SuspendTime      = GetTime( args.SuspendTime, DEF_SUSPEND );
  330.         OffTime          = GetTime( args.OffTime,     DEF_OFF );
  331.         IETime           = GetTime( args.ShiftTime,   DEF_SENDSHIFT );
  332.         SendShift        = args.SendShift;
  333.         NoMouse          = args.NoMouse;
  334.         rc = TRUE;
  335.  
  336.         FreeArgs( rdarg );
  337.     }
  338.  
  339.     return( rc );
  340. }
  341.  
  342.  
  343. static BOOL
  344. ParseArgs( VOID )
  345. {
  346.     return( ( BOOL ) ( WBMsg ? ParseWBArgs() : ParseCLIArgs() ) );
  347. }
  348.  
  349.  
  350. /******************** Commodity support ********************/
  351.  
  352.  
  353. /* This function runs on the input.device task context. Thus, we need to
  354.  * set smalldata base, make sure we don't call any nasty functions, and
  355.  * generally try to do our job quickly.
  356.  */
  357. static SAVEDS STKARGS VOID
  358. CxCustomFunc( register CxMsg *msg, CxObj *obj )
  359. {
  360.     struct InputEvent    *ie;
  361.     static LONG    LastSecs, LastIE;
  362.     LONG        diff;
  363.  
  364.     ie = ( struct InputEvent * ) CxMsgData( msg );
  365.  
  366.     switch( ie->ie_Class )
  367.     {
  368.         case IECLASS_RAWMOUSE:
  369.         case IECLASS_POINTERPOS:
  370.         case IECLASS_NEWPOINTERPOS:
  371.             if( NoMouse && ( ie->ie_Code == IECODE_NOBUTTON ) )
  372.             {
  373.                 /* Ignore mouse movements */
  374.                 break;
  375.             }
  376.  
  377.         case IECLASS_RAWKEY:
  378.             if( ie->ie_position.ie_addr == MAGIC )
  379.             {
  380.                 /* Ignore rawkeys we send out */
  381.                 break;
  382.             }
  383.  
  384.         case IECLASS_DISKREMOVED:
  385.         case IECLASS_DISKINSERTED:
  386.             StandbyCounter = StandbyTime;
  387.             SuspendCounter = SuspendTime;
  388.             OffCounter     = OffTime;
  389.  
  390.             if( State != DPMS_ON )
  391.             {
  392.                 State = DPMS_ON;
  393.                 RouteCxMsg( msg, Sender );
  394.             }
  395.  
  396.             break;
  397.  
  398.         case IECLASS_TIMER:
  399.             diff = ie->ie_TimeStamp.tv_secs - LastSecs;
  400.  
  401.             if( ( diff > 0 ) && ( State != FinalState ) && LastSecs )
  402.             {
  403.                 if( ( State < DPMS_STANDBY ) && ( StandbyCounter > 0 ) )
  404.                 {
  405.                     StandbyCounter -= diff;
  406.  
  407.                     if( StandbyCounter <= 0 )
  408.                     {
  409.                         State = DPMS_STANDBY;
  410.                         RouteCxMsg( msg, Sender );
  411.                     }
  412.                 }
  413.                 else if( ( State < DPMS_SUSPEND ) && ( SuspendCounter > 0 ) )
  414.                 {
  415.                     SuspendCounter -= diff;
  416.  
  417.                     if( SuspendCounter <= 0 )
  418.                     {
  419.                         State = DPMS_SUSPEND;
  420.                         RouteCxMsg( msg, Sender );
  421.                     }
  422.                 }
  423.                 else if( ( State < DPMS_OFF ) && ( OffCounter > 0 ) )
  424.                 {
  425.                     OffCounter -= diff;
  426.  
  427.                     if( OffCounter <= 0 )
  428.                     {
  429.                         State = DPMS_OFF;
  430.                         RouteCxMsg( msg, Sender );
  431.                     }
  432.                 }
  433.  
  434.                 if( SendShift && ( State > DPMS_ON ) )
  435.                 {
  436.                     diff = ie->ie_TimeStamp.tv_secs - LastIE;
  437.  
  438.                     if( diff > IETime )
  439.                     {
  440.                         LastIE = ie->ie_TimeStamp.tv_secs;
  441.                         ShiftDown.ie_TimeStamp = ie->ie_TimeStamp;
  442.                         ShiftUp.ie_TimeStamp   = ie->ie_TimeStamp;
  443.  
  444.                         /* Hm.. Maybe this would be better to do on the
  445.                          * main process' context. Oh well, not called
  446.                          * often anyway. ;)
  447.                          */
  448.                         AddIEvents( &ShiftDown );
  449.                     }
  450.                 }
  451.             }
  452.  
  453.             LastSecs = ie->ie_TimeStamp.tv_secs;
  454.             break;
  455.     }
  456. }
  457.  
  458.  
  459. static VOID
  460. FreeBroker( VOID )
  461. {
  462.     DeleteCxObjAll( Broker );
  463.     DeleteMsgPort( CxPort );
  464. }
  465.  
  466.  
  467. static BOOL
  468. InitBroker( VOID )
  469. {
  470.     BOOL    rc = FALSE;
  471.  
  472.     ShiftUp.ie_Class = ShiftDown.ie_Class = IECLASS_RAWKEY;
  473.     ShiftDown.ie_Code = 0x60,
  474.     ShiftUp.ie_Code = IECODE_UP_PREFIX | 0x60;
  475.     ShiftUp.ie_position.ie_addr = ShiftDown.ie_position.ie_addr = MAGIC;
  476.     ShiftDown.ie_NextEvent = &ShiftUp;
  477.  
  478.     StandbyCounter = StandbyTime;
  479.     SuspendCounter = SuspendTime;
  480.     OffCounter     = OffTime;
  481.     State          = DPMS_ON;
  482.  
  483.     if( StandbyTime )
  484.     {
  485.         FinalState = DPMS_STANDBY;
  486.     }
  487.     else if( SuspendTime )
  488.     {
  489.         FinalState = DPMS_SUSPEND;
  490.     }
  491.     else
  492.     {
  493.         FinalState = DPMS_OFF;
  494.     }
  495.  
  496.     if( CxPort = NewBroker.nb_Port = CreateMsgPort() )
  497.     {
  498.         LONG    err;
  499.  
  500.         if( Broker = CxBroker( &NewBroker, &err ) )
  501.         {
  502.             AttachCxObj( Broker, Custom = CxCustom( CxCustomFunc, ID_CUSTOM ) );
  503.             AttachCxObj( Custom, Sender = CxSender( CxPort, ID_SENDER ) );
  504.  
  505.             if( CxObjError( Broker ) || CxObjError( Custom ) )
  506.             {
  507.                 ErrRequest( "Not enough memory for Commodities objects!" );
  508.             }
  509.             else
  510.             {
  511.                 rc = TRUE;
  512.             }
  513.         }
  514.         else if( err != CBERR_DUP )
  515.         {
  516.             ErrRequest( "Couldn't create broker!" );
  517.         }
  518.     }
  519.     else
  520.     {
  521.         ErrRequest( "Couldn't create message port!" );
  522.     }
  523.  
  524.     if( !rc )
  525.     {
  526.         FreeBroker();
  527.     }
  528.  
  529.     return( rc );
  530. }
  531.  
  532.  
  533. static VOID
  534. HandleEvent( VOID )
  535. {
  536.     struct Screen    *wb;
  537.  
  538.     /* Configurable screen name? Maybe for 1.1... */
  539.     if( wb = LockPubScreen( "Workbench" ) )
  540.     {
  541.         /* Passing args via globals isn't the best perhaps, but it works. ;) */
  542.         CVideoCtrlTags( &wb->ViewPort,
  543.             SETVC_DPMSLevel,    State,
  544.         TAG_DONE );
  545.  
  546.         UnlockPubScreen( NULL, wb );
  547.     }
  548. }
  549.  
  550.  
  551. static BOOL
  552. HandleCxPort( VOID )
  553. {
  554.     CxMsg    *msg;
  555.     BOOL    run = TRUE;
  556.  
  557.     while( msg = ( CxMsg * ) GetMsg( CxPort ) )
  558.     {
  559.         LONG    id, type;
  560.  
  561.         id = CxMsgID( msg );
  562.         type = CxMsgType( msg );
  563.         ReplyMsg( ( struct Message * ) msg );
  564.  
  565.         switch( type )
  566.         {
  567.             case CXM_IEVENT:
  568.                 HandleEvent();
  569.                 break;
  570.  
  571.             case CXM_COMMAND:
  572.                 switch( id )
  573.                 {
  574.                     case CXCMD_DISABLE:
  575.                         ActivateCxObj( Broker, FALSE );
  576.                         break;
  577.  
  578.                     case CXCMD_ENABLE:
  579.                         ActivateCxObj( Broker, TRUE );
  580.                         break;
  581.  
  582.                     case CXCMD_KILL:
  583.                         run = FALSE;
  584.                         break;
  585.                 }
  586.  
  587.                 break;
  588.         }
  589.     }
  590.  
  591.     return( run );
  592. }
  593.  
  594.  
  595. /******************** Main program ********************/
  596.  
  597.  
  598. static VOID
  599. MainLoop( VOID )
  600. {
  601.     LONG    cxMask = 1 << CxPort->mp_SigBit;
  602.     BOOL    run = TRUE;
  603.  
  604.     ActivateCxObj( Broker, TRUE );
  605.  
  606.     while( run )
  607.     {
  608.         LONG    sigs;
  609.  
  610.         sigs = Wait( cxMask | SIGBREAKF_CTRL_C );
  611.  
  612.         if( sigs & cxMask )
  613.         {
  614.             if( !HandleCxPort() )
  615.             {
  616.                 run = FALSE;
  617.             }
  618.         }
  619.  
  620.         if( sigs & SIGBREAKF_CTRL_C )
  621.         {
  622.             run = FALSE;
  623.         }
  624.     }
  625. }
  626.  
  627.  
  628. static LONG
  629. Main( VOID )
  630. {
  631.     LONG    ret = RETURN_FAIL;
  632.  
  633.     if( OpenLibs() )
  634.     {
  635.         if( ParseArgs() )
  636.         {
  637.             if( InitBroker() )
  638.             {
  639.                 MainLoop();
  640.                 ret = RETURN_OK;
  641.  
  642.                 FreeBroker();
  643.             }
  644.         }
  645.  
  646.         CloseLibs();
  647.     }
  648.  
  649.     return( ret );
  650. }
  651.